<template>
  <div>
    <!-- 面包屑导航 -->
    <el-breadcrumb separator-class="el-icon-arrow-right">
      <el-breadcrumb-item :to="{ path: '/' }">首页</el-breadcrumb-item>
      <el-breadcrumb-item>权限管理</el-breadcrumb-item>
      <el-breadcrumb-item>角色列表</el-breadcrumb-item>
    </el-breadcrumb>
    <!-- //卡片视图 -->
    <el-card class="box-card">
      <el-row>
        <el-col>
          <el-button type="primary" @click="dialogVisible_add = true">添加角色</el-button>
        </el-col>
      </el-row>
      <br />
      <!-- //页面展示的主体内容 -->
      <el-table :data="tableData" border stripe>
        <!-- 展开列 -->
        <el-table-column type="expand">
          <template slot-scope="scope">
            <el-row v-for="(item1, i1) in scope.row.children" :class="['center','borderBottom', i1 === 0 ? 'borderTop' : '']" :key="item1.id">
              <!-- 渲染一级权限 -->
              <el-col :span="5">
                   <!-- 明明需要scope.row.id，为什么传的却是scope.row
                        因为为了解决删除后自动合并的问题  需要将删除后返回值中新的data重新赋值给scope.row.children -->
                <el-tag closable @close="handleClose(scope.row,item1.id)">{{ item1.authName }}</el-tag>
                <i class="el-icon-caret-right"></i>
              </el-col>
              <!-- 渲染二级权限 -->
              <el-col :span="19">
                <!-- 一行两列 -->
                <el-row v-for="(item2,i2) in item1.children" :key="item2.id" :class="['center',i2 === 0 ? '' : 'borderTop']">
                  <el-col :span="6">
                    <el-tag  type="success" closable @close="handleClose(scope.row,item2.id)">{{ item2.authName }}</el-tag>
                    <i class="el-icon-caret-right"></i>
                  </el-col>
                  <!-- 渲染三级权限 -->
                  <el-col :span="13">
                    <el-tag closable @close="handleClose(scope.row,item3.id)" v-for="item3 in item2.children" :key="item3.id" type="warning">
                      {{ item3.authName }}
                    </el-tag>
                  </el-col>
                </el-row>
              </el-col>
            </el-row>
          </template>
        </el-table-column>
        <!-- 索引列 -->
        <el-table-column type="index"></el-table-column>
        <el-table-column prop="roleName" label="角色名称"> </el-table-column>
        <el-table-column prop="roleDesc" label="角色描述"> </el-table-column>
        <el-table-column prop="roleDesc" label="操作" width="300px">
          <template slot-scope="scope">
            <el-button size="mini" type="primary" icon="el-icon-edit" @click="editList(scope.row.id)">编辑</el-button>
            <el-button size="mini" type="danger" icon="el-icon-delete" @click="deleteList(scope.row.id)">删除</el-button>
            <el-button size="mini" type="warning" icon="el-icon-coffee" @click="fenpeiList(scope.row)">分配权限</el-button>
          </template>
        </el-table-column>
      </el-table>
    </el-card>

    <!-- //添加角色 -->
    <el-dialog title="添加角色" :visible.sync="dialogVisible_add" width="40%" @close="cleaFromData('add')">
      <el-form :rules="rules" ref="addListREF" :model="addTablelist">
        <!-- 内容主体 -->
        <el-form-item prop="roleName">
          <el-input
            placeholder="请输入角色名称"
            v-model="addTablelist.roleName"
          ></el-input>
        </el-form-item>

        <el-form-item prop="roleDesc">
          <el-input
            placeholder="请输入角色描述"
            v-model="addTablelist.roleDesc"
          ></el-input>
        </el-form-item>
      </el-form>
      <!-- 底部区域 -->
      <span slot="footer" class="dialog-footer">
        <el-button @click="dialogVisible_add = false">取 消</el-button>
        <el-button type="primary" @click="addList">确 定</el-button>
      </span>
    </el-dialog>

    <!-- 编辑角色 -->
    <el-dialog title="编辑角色" :visible.sync="dialogVisible_edit" width="40%">
      <el-form :rules="rules" :model="editTablelist" ref="editREF">
        <el-form-item label="ID">
          <el-input v-model="editTablelist.id" disabled></el-input>
        </el-form-item>

        <!-- <el-form-item label="角色名称" prop="roleName">
          <el-input v-model="editTablelist.roleName"></el-input>
        </el-form-item> -->

        <el-form-item label="角色名称">
          <el-input v-model="editTablelist.roleName" disabled></el-input>
        </el-form-item>

        <el-form-item label="角色描述" prop="roleDesc">
          <el-input v-model="editTablelist.roleDesc"></el-input>
        </el-form-item>
      </el-form>

      <span slot="footer" class="dialog-footer">
        <el-button @click="dialogVisible_edit = false">取 消</el-button>
        <el-button type="primary" @click="editListOK">确 定</el-button>
      </span>
    </el-dialog>

    <!-- 分配权限 -->
    <el-dialog :visible.sync="dialogVisible_fenpei" width="50%"  @close="cleaFromData('fenpei')">
      <!-- 自定义dialog的title -->
      <template slot="title">
        <div style="color:red;font-weight:bolder;font-size:23px" id="fenpeiTitle">具体title在下方的innterHtml中</div>
      </template>
      <!-- 树形控件 -->
            <!-- show-checkbox   显示选择框
                default-expand-all   是否默认展开所有节点   需要注意的是，此时必须设置node-key="id"    详情看官方文档
            -->
      <el-tree :data="fenpeiData" :props="defaultList"
        show-checkbox
        default-expand-all
        node-key="id"
        :default-checked-keys="checkedKey"
        ref="TreeREF">
      </el-tree>

      <span slot="footer" class="dialog-footer">
        <el-button @click="dialogVisible_fenpei = false">取 消</el-button>
        <el-button type="primary" @click="setFenpeiquanxian">确 定</el-button>
      </span>
    </el-dialog>

  </div>
</template>

<script>
export default {
  name: "Roles",
  data() {
    return {
      tableData: [],

      //添加用户弹出框的显示与隐藏
      dialogVisible_add: false,
      //编辑用户弹出框的显示与隐藏
      dialogVisible_edit: false,
      // 分配劝权限的显示与隐藏
      dialogVisible_fenpei:false,
      //分配权限 默认选中的节点的ID值数组
      checkedKey:[],
      //设置分配权限时，使用的当前用户的id
      nowUserID:"",

      // 添加角色
      addTablelist: {
        roleName: "",
        roleDesc: "",
      },
      // 修改角色
      editTablelist: {
        id: "",
        roleName: "",
        roleDesc: "",
      },
      // 表单校验规则
      rules: {
        roleName: [
          { required: true, message: "请输入角色名称", trigger: "blur" },
        ],
        roleDesc: [
          { required: true, message: "请输入角色描述", trigger: "blur" },
          {
            min: 0,
            max: 10,
            message: "长度在0到10个字符",
            trigger: "blur",
          },
        ],
      },

      //分配权限 树形控件中的参数配置
      defaultList:{
        children:'children',
        label: 'authName'
      },
      // 存放分配权限的权限数据
      fenpeiData:[],
    };
  },
  //创建组件前进行axios请求
  created() {
    this.getRolesList();
  },
  //methods方法
  methods: {
    //获取角色列表
    async getRolesList() {
      const { data: rfsDate } = await this.$http.get("roles");
      if (rfsDate.meta.status != 200) {
        this.$message.error(
          "角色列表获取失败！！！！" +
            rfsDate.meta.status +
            "  " +
            rfsDate.meta.msg
        );
      } else {
        this.tableData = rfsDate.data;
      }
    },

    //进行角色的添加
    addList() {
      // 添加之前进行表格预验证
      this.$refs.addListREF.validate(async (bole) => {
        if (bole) {
          //正式发送请求
          const { data: fs } = await this.$http.post(
            "roles",
            this.addTablelist
          );
          if (fs.meta.status == 201) {
            this.$message({
              message: "角色添加成功！！！！",
              type: "success",
            });
            this.getRolesList();
          }
          this.dialogVisible_add = false;
        } else {
          this.$message.error("请输入正确的表单格式再进行提交！！");
        }
      });
    },

    //进行角色的编辑
    async editList(aaa) {
      //打开角色的编辑框
      this.dialogVisible_edit = true;
      //请求点击相应的用户信息
      const { data: ref } = await this.$http.get(`roles/${aaa}`);
      if (ref.meta.status == 200) {
        this.editTablelist.id = ref.data.roleId;
        this.editTablelist.roleName = ref.data.roleName;
        this.editTablelist.roleDesc = ref.data.roleDesc;
      } else {
        this.$message.error("信息请求错误！！！！");
      }
    },

    //编辑完成后，点击确定按钮进行修改
    editListOK() {
      this.$refs.editREF.validate(async (bool) => {
        if (bool) {
          const { data: rfe } = await this.$http.put(
            `roles/${this.editTablelist.id}`,
            this.editTablelist
          );
          if (rfe.meta.status == 200) {
            this.$message.success("修改成功！！！");
            //关闭编辑角色对话框
            this.dialogVisible_edit = false;
            //重新请求数据渲染页面
            this.getRolesList();
          } else {
            this.$message.error("数据写入错误！！！", rfe.meta.msg);
          }
        } else {
          this.$message.error("请填写正确的格式！！");
        }
      });
    },

    //删除用户操作
    deleteList(aaa) {
      this.$confirm("此操作将永久删除该角色, 是否继续?", "提示", {
        confirmButtonText: "确定",
        cancelButtonText: "取消",
        type: "warning",
      })
        .then(async () => {
          const { data: rfs } = await this.$http.delete(`roles/${aaa}`);
          if (rfs.meta.status == 200) {
            this.$message({
              type: "success",
              message: rfs.meta.msg,
            });
            //删除完毕后重新加载渲染页面
            this.getRolesList();
          } else {
            this.$message.error(rfs.meta.msg);
          }
        })
        .catch(() => {
          this.$message({
            type: "info",
            message: "已取消删除",
          });
        });
    },

    //对话框关闭时进行的数据清空操作
    cleaFromData(x) {
      // 清空添加角色对话框
      if (x === "add") {
        this.$refs.addListREF.resetFields();
      }
      //清空分配权限对话框
      if(x === "fenpei"){
        this.checkedKey = [];
      }
    },

    //移出权限标签
    handleClose(role,quanxianId) {
       this.$confirm('此操作将永久取消用户该权限, 是否继续?', '提示', {
          confirmButtonText: '确定',
          cancelButtonText: '取消',
          type: 'warning'
        }).then(async () => {
          //接收到了角色id，对应的要删除的权限id，开始axios请求 删除该权限
          const {data:res} = await this.$http.delete(`roles/${role.id}/rights/${quanxianId}`);
          //对返回的值进行判断
          if(res.meta.status == 200){
            this.$message({type: 'success', message: res.meta.msg});
            // 将返回值中新的data数据赋值给scope.row.children  使其防止页面重新被刷新
            role.children = res.data;
          }else{
            this.$message({type: 'info', message:'取消失败！！！原因为：'+ res.meta.msg});
          }
        }).catch(() => {
          this.$message({type: 'info',message: '已取消操作'});
        });
      },

    //显示分配权限
    async fenpeiList(role){
      //自定义分配权限dialog对话框的title
      document.querySelector("#fenpeiTitle").innerHTML = "分配权限---"+role.roleName;
      //将当前的用户的id保存起来，在设置分配权限时使用
      this.nowUserID = role.id;

      //进行显示分配权限的axios请求
      const {data:fes} = await this.$http.get("rights/tree");
      if(fes.meta.status == 200){
        this.fenpeiData = fes.data;
      }else{
        this.$message.error("获取权限失败！！"+fes.meta.msg)
      }
      //获取三级节点ID
      this.getLefKeys(role,this.checkedKey);
      //显示分配权限框
      this.dialogVisible_fenpei=true;
    },

    //通过递归的形式，获取角色下所有三级权限id 并将其保存到checkedKey数组中
    getLefKeys(item,arr){
      if(!item.children){
        return arr.push(item.id)
      }
      item.children.forEach(aa => this.getLefKeys(aa,arr))
    },

    //设置分配权限
    async setFenpeiquanxian(){
      // //返回目前被选中的节点的 key 所组成的数组
      // console.log("@@@",this.$refs.TreeREF.getCheckedKeys());
      // //返回目前半选中的节点所组成的数组
      // console.log("@@@",this.$refs.TreeREF.getHalfCheckedKeys());

      // 返回目前被选中的节点的 key 所组成的数组  和   返回目前半选中的节点所组成的数组     将其两个数组组成一个新数组
      const keys = [
        ...this.$refs.TreeREF.getCheckedKeys(),
        ...this.$refs.TreeREF.getHalfCheckedKeys()
      ];
      // 将组成的新数组转换为字符串，用逗号分隔
      const stringKeys = keys.join(',');
      //进行axios请求进行角色授权
      const {data:ref} = await this.$http.post(`roles/${this.nowUserID}/rights`,{rids:stringKeys});
      if(ref.meta.status === 200){
        this.$message.success("更新成功！！！！");
          //重新发送一遍请求数据 渲染页面
          this.getRolesList();
         //关闭对话框
        this.dialogVisible_fenpei=false;
      }else{
        this.$message.error("更新失败！！！"+ref.meta.status);
      }


    }
  },
};
</script>

<style scoped>
.el-tag {
  margin: 7px;
  margin-left: 10px;

}
/* .el-row {
  border-bottom: 1px solid #eee;
} */
.borderTop {
  border-top: 1px solid rgba(214, 208, 208, 0.801);
}
.borderBottom {
  border-bottom: 1px solid rgb(214, 208, 208,  0.801);
}
/* 垂直居中对齐 */
.center {
  display: flex;
  align-items: center;
}

</style>

